import { ItemData, 头盔, 防弹衣, 近战武器 as 近战武器, 背包, 手枪, 突击步枪, 冲锋枪, 射手步枪, 栓动步枪, 轻机枪, 霰弹枪, 卡宾枪, 子弹, 投掷物, 钥匙, 药品, 食物, SuppliesData, 战利品, PlayerData, SeasonData, Money } from '../../Datas/Data';
import { InventoryType } from '../../UI/InventoryPanel';
import { Constant, ItemType, SuppliesType } from '../Const/Constant';
import { ResourceUtil } from '../Utils/ResourceUtil';
import { ZTool } from '../Utils/ZTool';
import { EventManager, MyEvent } from './EventManager';
import { PoolManager } from './PoolManager';
import PrefsManager from './PrefsManager';

export class DataManager {
    static ItemDatas: Map<ItemType, ItemData[]>;
    static SuppliesDatas: Map<SuppliesType, SuppliesData[]>;
    static JunXuItems: ItemData[];//军需
    static PlayerItems: ItemData[];
    static SeasonDatas: SeasonData[];
    static PlayerData: PlayerData;
    static Names: string[] = [];

    public static get Money(): number {
        return PrefsManager.GetNumber(Constant.Key.Money, 0);
    }
    public static set Money(value: number) {
        PrefsManager.SetNumber(Constant.Key.Money, value)
        EventManager.Scene.emit(MyEvent.RefreshMoney);
    }
    public static get SeasonLv(): number {
        // return 3;
        return ZTool.Clamp(Math.floor(DataManager.EXP / 1000), 0, 80);
    }
    public static get EXP(): number {
        return PrefsManager.GetNumber(Constant.Key.EXP, 0);
    }
    public static set EXP(value: number) {
        value = Math.floor(value);
        PrefsManager.SetNumber(Constant.Key.EXP, value)
    }

    public static async LoadData() {
        DataManager.ItemDatas = new Map();
        DataManager.SuppliesDatas = new Map();
        DataManager.JunXuItems = [];
        DataManager.PlayerItems = [];
        DataManager.SeasonDatas = [];

        PoolManager.GenerateNodesToPool("Prefabs/UI/SeasonItem", 100);

        return new Promise((resolve, reject) => {
            //玩家装备数据
            if (PrefsManager.GetItem(Constant.Key.PlayerData)) {
                let data = JSON.parse(PrefsManager.GetItem(Constant.Key.PlayerData));
                this.PlayerData = new PlayerData(data.Helmet, data.Bulletproof, data.Weapon_0, data.Weapon_1, data.Pistol, data.MeleeWeapon, data.BackpackItems);
            } else {
                this.PlayerData = new PlayerData();
            }
            console.log(`[玩家装备数据]:`, this.PlayerData);

            //玩家仓库数据
            if (PrefsManager.GetItem(Constant.Key.Items)) {
                let data = JSON.parse(PrefsManager.GetItem(Constant.Key.Items));
                for (let i = 0; i < data.length; i++) {
                    this.PlayerItems.push(data[i]);
                }
            }
            console.log(`[玩家仓库数据]:`, this.PlayerItems);

            ResourceUtil.LoadJson("Name").then((ja: cc.JsonAsset) => {
                let data = ja.json as any;
                this.Names = data.Names;
            });

            //所有物品数据
            ResourceUtil.LoadJson("Data").then((ja: cc.JsonAsset) => {
                let data = ja.json as any;
                DataManager.ItemDatas.set(ItemType.金钱, []);
                DataManager.ItemDatas.get(ItemType.金钱).push(new Money("金钱", "金钱"));

                DataManager.ItemDatas.set(ItemType.头盔, []);
                for (let i = 0; i < data.头盔.length; i++) {
                    let e = data.头盔[i];
                    DataManager.ItemDatas.get(ItemType.头盔).push(new 头盔(e.Name, e.Type, e.Price, e.Position, e.Lv));
                }

                DataManager.ItemDatas.set(ItemType.防弹衣, []);
                for (let i = 0; i < data.防弹衣.length; i++) {
                    let e = data.防弹衣[i];
                    DataManager.ItemDatas.get(ItemType.防弹衣).push(new 防弹衣(e.Name, e.Type, e.Price, e.Position, e.Lv));
                }

                DataManager.ItemDatas.set(ItemType.背包, []);
                for (let i = 0; i < data.背包.length; i++) {
                    let e = data.背包[i];
                    DataManager.ItemDatas.get(ItemType.背包).push(new 背包(e.Name, e.Type, e.Price, e.Lv));
                }

                DataManager.ItemDatas.set(ItemType.手枪, []);
                for (let i = 0; i < data.手枪.length; i++) {
                    let e = data.手枪[i];
                    DataManager.ItemDatas.get(ItemType.手枪).push(new 手枪(e.Name, e.Type, e.Price, e.Damage, e.FireRate, e.Recoil, e.Desc, e.FirePosition));
                }

                DataManager.ItemDatas.set(ItemType.突击步枪, []);
                for (let i = 0; i < data.突击步枪.length; i++) {
                    let e = data.突击步枪[i];
                    DataManager.ItemDatas.get(ItemType.突击步枪).push(new 突击步枪(e.Name, e.Type, e.Price, e.Damage, e.FireRate, e.Recoil, e.Desc, e.FirePosition));
                }

                DataManager.ItemDatas.set(ItemType.冲锋枪, []);
                for (let i = 0; i < data.冲锋枪.length; i++) {
                    let e = data.冲锋枪[i];
                    DataManager.ItemDatas.get(ItemType.冲锋枪).push(new 冲锋枪(e.Name, e.Type, e.Price, e.Damage, e.FireRate, e.Recoil, e.Desc, e.FirePosition));
                }

                DataManager.ItemDatas.set(ItemType.射手步枪, []);
                for (let i = 0; i < data.射手步枪.length; i++) {
                    let e = data.射手步枪[i];
                    DataManager.ItemDatas.get(ItemType.射手步枪).push(new 射手步枪(e.Name, e.Type, e.Price, e.Damage, e.FireRate, e.Recoil, e.Desc, e.FirePosition));
                }

                DataManager.ItemDatas.set(ItemType.栓动步枪, []);
                for (let i = 0; i < data.栓动步枪.length; i++) {
                    let e = data.栓动步枪[i];
                    DataManager.ItemDatas.get(ItemType.栓动步枪).push(new 栓动步枪(e.Name, e.Type, e.Price, e.Damage, e.FireRate, e.Recoil, e.Desc, e.FirePosition));
                }

                DataManager.ItemDatas.set(ItemType.轻机枪, []);
                for (let i = 0; i < data.轻机枪.length; i++) {
                    let e = data.轻机枪[i];
                    DataManager.ItemDatas.get(ItemType.轻机枪).push(new 轻机枪(e.Name, e.Type, e.Price, e.Damage, e.FireRate, e.Recoil, e.Desc, e.FirePosition));
                }

                DataManager.ItemDatas.set(ItemType.霰弹枪, []);
                for (let i = 0; i < data.霰弹枪.length; i++) {
                    let e = data.霰弹枪[i];
                    DataManager.ItemDatas.get(ItemType.霰弹枪).push(new 霰弹枪(e.Name, e.Type, e.Price, e.Damage, e.FireRate, e.Recoil, e.Desc, e.FirePosition));
                }

                DataManager.ItemDatas.set(ItemType.卡宾枪, []);
                for (let i = 0; i < data.卡宾枪.length; i++) {
                    let e = data.卡宾枪[i];
                    DataManager.ItemDatas.get(ItemType.卡宾枪).push(new 卡宾枪(e.Name, e.Type, e.Price, e.Damage, e.FireRate, e.Recoil, e.Desc, e.FirePosition));
                }

                DataManager.ItemDatas.set(ItemType.近战武器, []);
                for (let i = 0; i < data.近战武器.length; i++) {
                    let e = data.近战武器[i];
                    DataManager.ItemDatas.get(ItemType.近战武器).push(new 近战武器(e.Name, e.Type, e.Price, e.Damage, e.FireRate));
                }

                DataManager.ItemDatas.set(ItemType.子弹, []);
                for (let i = 0; i < data.子弹.length; i++) {
                    let e = data.子弹[i];
                    DataManager.ItemDatas.get(ItemType.子弹).push(new 子弹(e.Name, e.Type, e.Price));
                }

                DataManager.ItemDatas.set(ItemType.投掷物, []);
                for (let i = 0; i < data.投掷物.length; i++) {
                    let e = data.投掷物[i];
                    DataManager.ItemDatas.get(ItemType.投掷物).push(new 投掷物(e.Name, e.Type, e.Price, e.Lv));
                }

                DataManager.ItemDatas.set(ItemType.钥匙, []);
                for (let i = 0; i < data.钥匙.length; i++) {
                    let e = data.钥匙[i];
                    DataManager.ItemDatas.get(ItemType.钥匙).push(new 钥匙(e.Name, e.Type, e.Price, e.Lv));
                }

                DataManager.ItemDatas.set(ItemType.药品, []);
                for (let i = 0; i < data.药品.length; i++) {
                    let e = data.药品[i];
                    DataManager.ItemDatas.get(ItemType.药品).push(new 药品(e.Name, e.Type, e.Price, e.Time, e.HP));
                }

                DataManager.ItemDatas.set(ItemType.食物, []);
                for (let i = 0; i < data.食物.length; i++) {
                    let e = data.食物[i];
                    DataManager.ItemDatas.get(ItemType.食物).push(new 食物(e.Name, e.Type, e.Price, e.Lv));
                }

                DataManager.ItemDatas.set(ItemType.战利品, []);
                for (let i = 0; i < data.战利品.length; i++) {
                    let e = data.战利品[i];
                    DataManager.ItemDatas.get(ItemType.战利品).push(new 战利品(e.Name, e.Type, e.Value));
                }

                for (let i = 0; i < data.物资.length; i++) {
                    let e = data.物资[i];
                    let type: SuppliesType = SuppliesType[`${e.Type}`];

                    if (!this.SuppliesDatas.has(type)) {
                        this.SuppliesDatas.set(type, []);
                    }

                    this.SuppliesDatas.get(type).push(new SuppliesData(e.Name, e.Type, e.Time, e.Count, e.NeedKey, e.HasOpenState));
                }

                for (let i = 0; i < data.军需.length; i++) {
                    let e = data.军需[i];
                    let type = ItemType[`${e.Type}`];
                    let originData;

                    if (DataManager.ItemDatas.has(type)) {
                        if (DataManager.ItemDatas.get(type).find(a => a.Name == e.Origin)) {
                            originData = DataManager.ItemDatas.get(type).find(a => a.Name == e.Origin);
                            switch (type) {
                                case ItemType.冲锋枪:
                                    DataManager.JunXuItems.push(new 冲锋枪(e.Name, e.Type, originData.Price, originData.Damage, originData.FireRate, originData.Recoil, originData.Desc, originData.FirePosition));
                                    break;
                                case ItemType.突击步枪:
                                    DataManager.JunXuItems.push(new 突击步枪(e.Name, e.Type, originData.Price, originData.Damage, originData.FireRate, originData.Recoil, originData.Desc, originData.FirePosition));
                                    break;
                                case ItemType.栓动步枪:
                                    DataManager.JunXuItems.push(new 栓动步枪(e.Name, e.Type, originData.Price, originData.Damage, originData.FireRate, originData.Recoil, originData.Desc, originData.FirePosition));
                                    break;
                                case ItemType.手枪:
                                    DataManager.JunXuItems.push(new 手枪(e.Name, e.Type, originData.Price, originData.Damage, originData.FireRate, originData.Recoil, originData.Desc, originData.FirePosition));
                                    break;
                                case ItemType.射手步枪:
                                    DataManager.JunXuItems.push(new 射手步枪(e.Name, e.Type, originData.Price, originData.Damage, originData.FireRate, originData.Recoil, originData.Desc, originData.FirePosition));
                                    break;
                                case ItemType.轻机枪:
                                    DataManager.JunXuItems.push(new 轻机枪(e.Name, e.Type, originData.Price, originData.Damage, originData.FireRate, originData.Recoil, originData.Desc, originData.FirePosition));
                                    break;
                                case ItemType.霰弹枪:
                                    DataManager.JunXuItems.push(new 霰弹枪(e.Name, e.Type, originData.Price, originData.Damage, originData.FireRate, originData.Recoil, originData.Desc, originData.FirePosition));
                                    break;
                            }
                        }
                    }
                }

                for (let i = 0; i < data.赛季.length; i++) {
                    let e = data.赛季[i];
                    let newData = new SeasonData(e.Name_1, e.Name_2, e.Type, e.Count_1, e.Count_2, e.IsJunXu);
                    this.SeasonDatas.push(newData);
                }

                console.log(`[所有物品数据]:`, DataManager.ItemDatas);
                console.log(`[所有军需数据]:`, DataManager.JunXuItems);
                console.log(`[所有补给数据]:`, DataManager.SuppliesDatas);
                console.log(`[所有赛季数据]:`, DataManager.SeasonDatas);

                resolve([]);
            });

        });
    }

    public static GetItemData(type: ItemType, name: string) {
        return DataManager.ItemDatas.get(type).find(e => e.Name == name);
    }

    //添加玩家的道具
    public static AddPlayerItem(data: ItemData, fromShop: boolean = false) {
        let type = ItemType[data.Type];

        if (fromShop) {
            if (DataManager.ItemDatas.get(type).find(e => e.Name == data.Name)) {
                data = ZTool.DeepCopy(DataManager.ItemDatas.get(type).find(e => e.Name == data.Name));
            }
        }

        if (data) {
            console.log(`向仓库添加:`, data);
            this.PlayerItems.push(data);
            this.SaveData();
            EventManager.Scene.emit(MyEvent.RefreshGoodsItem);
        }
    }

    //移除玩家的道具
    public static RemovePlayerItem(data: ItemData) {
        if (this.PlayerItems.indexOf(data) != -1) {
            this.PlayerItems.splice(this.PlayerItems.indexOf(data), 1);
            this.SaveData();
            EventManager.Scene.emit(MyEvent.RefreshGoodsItem);
            return true;
        }

        return false;
    }

    public static SaveData() {
        PrefsManager.SetItem(Constant.Key.Items, JSON.stringify(this.PlayerItems));
        PrefsManager.SetItem(Constant.Key.PlayerData, JSON.stringify(this.PlayerData));
    }

    //装备物品
    public static AddEquippedItem(type: InventoryType, data: ItemData): boolean {
        switch (type) {
            case InventoryType.Helmet:
                if (this.PlayerData.Helmet != null) return false;
                this.PlayerData.Helmet = data;
                break;
            case InventoryType.Bulletproof:
                if (this.PlayerData.Bulletproof != null) return false;
                this.PlayerData.Bulletproof = data;
                break;

            case InventoryType.Weapon_0:
                if (this.PlayerData.Weapon_0 != null) return false;
                this.PlayerData.Weapon_0 = data;
                break;

            case InventoryType.Weapon_1:
                if (this.PlayerData.Weapon_1 != null) return false;
                this.PlayerData.Weapon_1 = data;
                break;

            case InventoryType.Pistol:
                if (this.PlayerData.Pistol != null) return false;
                this.PlayerData.Pistol = data;
                break;

            case InventoryType.MeleeWeapon:
                if (this.PlayerData.MeleeWeapon != null) return false;
                this.PlayerData.MeleeWeapon = data;
                break;

        }
        this.RemovePlayerItem(data);
        this.SaveData();
        return true;
    }

    //移除玩家已经装备的道具
    public static RemovePlayerEquippedItem(data: ItemData) {
        for (const key in this.PlayerData) {
            if (this.PlayerData.hasOwnProperty(key) && this.PlayerData[key] == data) {
                this.PlayerData[key] = null;
                console.log(`移除已经装备 ${key}：`, data);
                this.SaveData();
                return true;
            }
        }

        return false;
    }

    //向装备的枪里添加子弹
    public static AddBulletToEquippedItem(data: ItemData) {
        if (this.PlayerData.Weapon_0 != null) {
            let equippedData = this.PlayerData.Weapon_0 as any;
            if (equippedData.Desc == data.Name && equippedData.BulletCount != 60) {
                equippedData.BulletCount = 60;
                this.RemovePlayerItem(data);
                this.SaveData();
                return true;
            }
        }

        if (this.PlayerData.Weapon_1 != null) {
            let equippedData = this.PlayerData.Weapon_1 as any;
            if (equippedData.Desc == data.Name && equippedData.BulletCount != 60) {
                equippedData.BulletCount = 60;
                this.RemovePlayerItem(data);
                this.SaveData();
                return true;
            }
        }

        if (this.PlayerData.Pistol != null) {
            let equippedData = this.PlayerData.Pistol as any;
            if (equippedData.Desc == data.Name && equippedData.BulletCount != 60) {
                equippedData.BulletCount = 60;
                this.RemovePlayerItem(data);
                this.SaveData();
                return true;
            }
        }

        return false;
    }

    //向背包添加物品
    public static AddItemToBackpack(data: ItemData) {
        if (DataManager.PlayerData.BackpackItems.length >= PlayerData.MaxBackpackItems) return false;
        DataManager.PlayerData.BackpackItems.push(data);
        this.SaveData();
        EventManager.Scene.emit(MyEvent.RefreshBackpackGoodsItem);
        console.log(`向背包添加:`, data);
        return true;
    }

    //向背包移除物品
    public static RemoveItemFromBackpack(data: ItemData) {
        if (this.PlayerData.BackpackItems.indexOf(data) != -1) {
            this.PlayerData.BackpackItems.splice(this.PlayerData.BackpackItems.indexOf(data), 1);
            this.SaveData();
            EventManager.Scene.emit(MyEvent.RefreshBackpackGoodsItem);
            console.log(`向背包移除:`, data);
            return true;
        }
        return false;
    }

    //随机生成玩家数据
    public static GeneratePlayerData(): PlayerData {
        let data = new PlayerData();

        //名字
        data.Name = this.Names[ZTool.GetRandomInt(0, this.Names.length)];
        //头盔
        data.Helmet = DataManager.ItemDatas.get(ItemType.头盔)[ZTool.GetRandomInt(0, DataManager.ItemDatas.get(ItemType.头盔).length)] as any;
        //防弹衣
        data.Bulletproof = DataManager.ItemDatas.get(ItemType.防弹衣)[ZTool.GetRandomInt(0, DataManager.ItemDatas.get(ItemType.防弹衣).length)] as any;
        //枪
        let isPistol = Math.random() > 0.8 ? true : false;
        if (isPistol) {
            data.Pistol = DataManager.ItemDatas.get(ItemType.手枪)[ZTool.GetRandomInt(0, DataManager.ItemDatas.get(ItemType.手枪).length)] as any;
            (data.Pistol as any).BulletCount = ZTool.GetRandomInt(0, 80);
        } else {
            let gunType = ItemData.GunTypes[ZTool.GetRandomInt(0, ItemData.MainGunTypes.length)];
            data.Weapon_0 = DataManager.ItemDatas.get(gunType)[ZTool.GetRandomInt(0, DataManager.ItemDatas.get(gunType).length)] as any;
            (data.Weapon_0 as any).BulletCount = ZTool.GetRandomInt(0, 80);
        }

        //物品
        for (let i = 0; i < ZTool.GetRandomInt(0, 3); i++) {
            data.BackpackItems.push(DataManager.ItemDatas.get(ItemType.子弹)[ZTool.GetRandomInt(0, DataManager.ItemDatas.get(ItemType.子弹).length)] as any);
        }

        for (let i = 0; i < ZTool.GetRandomInt(0, 3); i++) {
            data.BackpackItems.push(DataManager.ItemDatas.get(ItemType.战利品)[ZTool.GetRandomInt(0, DataManager.ItemDatas.get(ItemType.战利品).length)] as any);
        }

        return data;
    }

    public static SetSeasonItemGot(index: number, goodsIndex: number) {
        PrefsManager.SetBool(`${Constant.Key.UnlockSeason}_${index}_${goodsIndex}`, true)
    }

    public static GetSeasonItemGot(index: number, goodsIndex: number): boolean {
        return PrefsManager.GetBool(`${Constant.Key.UnlockSeason}_${index}_${goodsIndex}`);
    }
}